package com.twang.stock.task.old;

import com.alibaba.fastjson.JSONObject;
import com.twang.stock.Entity.ShiShiData;
import com.twang.stock.common.CommonUtils;
import com.twang.stock.entity.StockFromTHSDto;
import com.twang.stock.entity.StockVolInfo;
import com.twang.stock.mapper.StockVolInfoMapper;
import com.twang.stock.redis.RedisUtil;
import com.twang.stock.service.impl.MinutesVolRuleService;
import com.twang.stock.service.jinyan.CommonService;
import com.twang.stock.email.SendmailService;
import com.twang.stock.threadPool.AsycTaskExecutorConfig;
import com.twang.stock.utils.date.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 计算分时成交量   每分钟更新一次
 */
@Slf4j
@Service
public class ExcuteWarningTask extends  BaseTask {
    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36";
    private static String COOKIE = "v=A-9dbpYI04Zt6Ne6Um7b5cTjfgj6lEOF3ehHqgF8i95lUAH-CWTTBu241-AS";


    @Autowired
    private MinutesVolRuleService minutesVolRuleService;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private StockVolInfoMapper stockVolInfoMapper;

    @Autowired
    private AsycTaskExecutorConfig asycTaskExecutorConfig;

    @Autowired
    private SendmailService sendmailService;
    @Autowired
    private CommonService commonService;

    //@Scheduled(cron = "0 0/1 * * * ?")作废
    public void execute() {
        log.info(" 执行 start time={}", DateUtils.getNow());
        try {
            if (!isWorkTradeTime()) {
                return;
            }
            if (!isworkTime()) {
                return;
            }
            //每一秒都用异步处理
            setQueryStockInfo();
        } catch (Exception e) {
            sendmailService.insertEvent(CommonUtils.TASK_NAME_RULE_5, CommonUtils.FAILE_MESSAGE + JSONObject.toJSONString(e), "ERROR", CommonUtils.RULE_EXCEPTION);
        }
        log.info(" 执行 end time={}", DateUtils.getNow());
    }

    private Boolean isworkTime() {
        //使用Date
        Date d = new Date();
        //格式化时间串,HH:MM:SS分别是时分秒，这里只判断分钟，有mm就够了
        //需要秒的话，就mm：ss，下面就判断是否 00:00
        SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
        String timestr = sdf.format(d);
        //判断是否为需要的时间，比如整点时分钟为00
        String regex = timestr.split(":")[1];
        if (regex.equals("59")) {
            return Boolean.TRUE;
        } else {
            return Boolean.FALSE;
        }
    }

    /**
     * 查询所有
     *
     * @throws Exception
     */
    private void setQueryStockInfo() throws Exception {
        List<ShiShiData> list = null;
                //queryDataService.query(Boolean.FALSE);
        list.forEach(data -> {
            forDataSave(data);
        });
    }

    public void forDataSave(ShiShiData data) {
        String key = "maxVol_" + data.getCode() + "_" + data.getGetdate();
        String forDataSaveKey = "forDataSave_" + data.getCode() + "_" + data.getGetdate();
        Integer maxVol = null;
        ShiShiData latsData = null;
        if (null == redisUtil.get(key)) {
            maxVol = 0;
        } else {
            maxVol = (Integer) redisUtil.get(key);
        }
        if (null == redisUtil.get(forDataSaveKey)) {
            latsData = data;
        } else {
            latsData = (ShiShiData) redisUtil.get(forDataSaveKey);
        }
        Integer newVol = data.getSumvol() - latsData.getSumvol();
        if (newVol > maxVol) {
            maxVol = newVol;
            //异步通知，不阻塞调度
            asycTaskExecutorConfig.taskQueueExecutor().execute(() ->
                    minutesVolRuleService.yiDongStock("【分时异动】" + data.getGpname() + "   瞬时成交量：" + newVol, data.getGpname(), data.getCode(), CommonUtils.RULE_1)
            );
        }
        //分时总成交
        // insert(data);
        //更新缓存
        redisUtil.set(key, maxVol, 3600 * 23);
        redisUtil.set(forDataSaveKey, data, 3600 * 23);
        try {
            //执行规则-1
            Integer finalMaxVol1 = maxVol;
            //异步通知，不阻塞调度
            asycTaskExecutorConfig.taskQueueExecutor().execute(() ->
                    minutesVolRuleService.excute(finalMaxVol1, data.getSumvol(), data.getCode(), data.getPrice())
            );
        } catch (Exception e) {
            log.error("exception e={}", e);
        }
    }

    /**
     * @param data
     */
    public void insert(ShiShiData data) {
        StockVolInfo info = new StockVolInfo();
        info.setCode(data.getCode());
        info.setName(data.getGpname());
        info.setPricae(new BigDecimal(data.getPrice()));
        info.setTotalVol(data.getSumvol());
        info.setTime(data.getGptime() + "");
        info.setCreateTime(new Date());
        stockVolInfoMapper.insert(info);
    }

    /**
     * http://d.10jqka.com.cn/v2/realhead/hs_603758/last.js
     */
    public static   StockFromTHSDto getData(String code) throws Exception {
        if(StringUtils.isEmpty(code)){
            throw new Exception("代碼不能為空！");
        }
        String url=new StringBuffer("").append("http://d.10jqka.com.cn/v2/realhead/hs").append(code).append("/last.js").toString();
        // HttpClient 超时配置
        RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD)
                .setConnectionRequestTimeout(6000).setConnectTimeout(6000).build();
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(globalConfig).build();
        String str = getHtmlStrByUrl(url, httpClient, null, USER_AGENT);
        String data = str.split("\\(")[1];
        JSONObject obj = JSONObject.parseObject(data.split("\\)")[0]);
        Object jsonObject= obj.get("items");
        StockFromTHSDto result = JSONObject.parseObject(JSONObject.toJSONString(jsonObject),StockFromTHSDto.class);
        return result;
    }

    public static void main(String[] args) throws Exception {
       //

        StockFromTHSDto result = getData("1A0001");
        System.out.println(result);
    }

    public static String getHtmlStrByUrl(String url, CloseableHttpClient httpClient, String COOKIE, String USER_AGENT) throws Exception {
        HttpGet httpGetForFName = new HttpGet(url);
        httpGetForFName.addHeader("User-Agent", USER_AGENT);
        httpGetForFName.addHeader("Cookie", getCOOKIE());
        httpGetForFName.addHeader("Content-Type", "text/html; charset=GBK");
        httpGetForFName.addHeader("Accept-Encoding", "gzip, deflate");
        httpGetForFName.addHeader("Connection", "keep-alive");
        // 发送请求，并执行
        CloseableHttpResponse response;
        String html = "";
        try {
            response = httpClient.execute(httpGetForFName);
            // response植入cookie
            InputStream in = response.getEntity().getContent();
            html = convertStreamToString(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return html;
    }

    private static String getCOOKIE() throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");
        ClassPathResource classPathResource = new ClassPathResource("static/js/aes.min.js");
        InputStreamReader reader=   new InputStreamReader(classPathResource.getInputStream());
        engine.eval(reader);
        if (engine instanceof Invocable) {
            Invocable invoke = (Invocable) engine; // 调用merge方法，并传入两个参数
            String c = (String) invoke.invokeFunction("v");
            COOKIE = "v=" + c;
        }
        reader.close();
        return COOKIE;
    }

    public static String convertStreamToString(InputStream in) {
        StringBuilder sb = new StringBuilder();
        try {

            InputStreamReader isr = new InputStreamReader(in, "gbk");
            BufferedReader reader = new BufferedReader(isr);
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "/n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();

    }

}
